<?php
namespace App\Repository\Db;

use App\Model\Admin;
use App\Model\Setting;
use App\Repository\Contracts\AdminInterface;
use App\Exceptions\ValidateException;
use App\Repository\Contracts\MenuInterface;
use App\Repository\Contracts\OperationInterface;
use App\Repository\Contracts\RoleMenuInterface;
use App\Repository\Contracts\SettingInterface;
use App\Support\Helper\CommonHelper;

/**
 * @Author:: HuangYin
 * @DateTime: 2017/6/7 22:35
 */
class AdminRepository extends Repository implements AdminInterface
{
    protected $rules = [
        'created' => [
            'role_id'   => 'required|exists:role,id',
            'store_id'   => 'required',
            'phone'     => 'required|regex:/^1[34578][0-9]{9}$/|unique:admin,phone',
            'password'  => 'required|min:6|max:20',
            'rePassword'=> 'required|min:6|max:20',
            'real_name' => 'required|min:2|max:32|unique:admin,real_name'
        ],
        'updated' => [
            'phone'     => 'required|regex:/^1[34578][0-9]{9}$/|unique:admin',
            'password'  => 'required|min:6|max:20',
            'rePassword'=> 'required|min:6|max:20',
            'real_name' => 'sometimes|min:2|max:10',
        ],
        'login'   => [
            'phone' => 'required',
            'password' => 'required',
        ]
    ];

    protected $messages = [
        'role_id.required'          => "角色不能为空",
        'role_id.exists'            => "角色不存在",
        'store_id.required'         => "门店 ID 不能为空",
        'phone.required'            => '手机号码不能为空',
        'phone.regex'               => '手机号码不合法',
        'phone.unique'              => '手机号码已存在',
        'real_name.required'        => "姓名不能为空",
        'real_name.min'             => "姓名长度最小2个字",
        'real_name.max'             => "姓名长度最大10个字",
        'password.required'         => "密码不能为空",
        'password.min'              => "密码长度最小6个字",
        'password.max'              => "密码长度最大20个字",
        'login.username.required'   => "请填写用户名",
        'login.password.required'   => "请输入密码",
    ];

    protected function modelName()
    {
        return 'App\Model\Admin';
    }

    public function created(array $data)
    {
        $this->validate($data, 'created');
        if ($data['password'] === $data['rePassword']) {
            $salt = str_random(6);
            $save = [
                'role_id' => $data['role_id'], 'store_id' => $data['store_id'], 'phone' => $data['phone'],
                'salt' => $salt, 'password' => CommonHelper::hashPassword($salt, $data['password']),
                'real_name' => $data['real_name']
            ];
            if (!$this->container->make(SettingInterface::class)->findByName(Setting::STORE_CONFIG)) {
                $config = [
                    'storeName' => $data['storeName'], 'storeId' => $data['store_id'], 'shopkeeper' => $data['shopkeeper'],
                    'phone' => $data['phone'], 'tel' => $data['tel'], 'address' => $data['address']
                ];
                $this->container->make(SettingInterface::class)->created([
                    'name' => Setting::STORE_CONFIG, 'config' => json_encode($config)
                ]);
            }
            $lastId = $this->save($save);
            $lastId && $this->update(['uid' => $lastId], $lastId, 'id');

            return $lastId;
        }

        throw new ValidateException('两次输入的密码不同！');
    }

    public function detail($id)
    {
        return $this->find($id);
    }

    public function checkToken($token)
    {
        $result = $this->findBy('token', $token);
        if ($result && CommonHelper::getToken($result->token)['prefix'] == 'backend') {
            return $result->token;
        }

        return null;
    }

    public function lists($limit, $page)
    {
        $query = $this->model;
        $total = $query->count();
        $list = $query->orderBy('id', 'desc')->simplePaginate($limit, ['*'], 'page', $page);

        return $this->simplePaginate('list', $list->items(), $total, ceil($total/$limit), $page);
    }

    public function findByPhone($phone)
    {
        return $this->findBy('phone', $phone);
    }

    public function updated($id, array $data)
    {
        $this->validate($data, 'updated', ['phone' => $id]);
        if ($data['password'] === $data['rePassword']) {
            $salt = str_random(6);
            $save = [
                'phone' => $data['phone'], 'real_name' => $data['real_name'], 'salt' => $salt,
                'password' => CommonHelper::hashPassword($salt, $data['password'])
            ];

            return $this->update($save, $id, 'id');
        }

        throw new ValidateException('两次输入的密码不同！');
    }

    public function updatePwd($id, $password, $newPassword)
    {
        if (!$id || !$password || !$newPassword) {
            return false;
        }
        $user = $this->find($id, ['salt', 'password']);
        if (!$user) {
            throw new ValidateException('该用户不存在！');
        }
        if (CommonHelper::hashPassword($user->salt, $password) !== $user->password) {
            throw new ValidateException('原始密码不正确！');
        }
        $data['salt'] = str_random(6);
        $data['password'] = CommonHelper::hashPassword($data['salt'], $newPassword);

        return $this->update($data, $id, 'id');
    }

    public function resetPwd($id)
    {
        $user = $this->find($id);
        if (empty($user)) {
            return false;
        }

        $data['salt'] = str_random(6);
        $newPassword = str_random(8);
        $data['password'] = CommonHelper::hashPassword($data['salt'], $newPassword);

        // TODO 新密码发送到用户手机
        //$this->container->make(MessageService::class)->sendMessage($user->phone, 1); 短信模板 ID

        return $this->update($data, $id, 'id');
    }

    public function signIn(array $data)
    {
        $this->validate($data, 'login');
        $user = $this->findByPhone($data['phone']);
        if (!$user) {
            throw new ValidateException('用户不存在！');
        }
        if (CommonHelper::hashPassword($user->salt, $data['password']) !== $user->password) {
            throw new ValidateException('您输入的密码有误');
        }
        if ($user->token) {
            throw new ValidateException('请不要重复登录');
        }
        $token = CommonHelper::setToken(json_encode(['uid' => $user->uid, 'storeId' => $user->store_id]));
        $this->update(['token' => $token], $user->uid, 'uid');
        $result['info'] = $user->toArray();
        if ($user->role_id === Admin::STORE_CLERK) {
            $number = date('YmdHis', time()) . mt_rand(100, 1000);
            $source = [
                'uid' => $user->uid, 'number' => $number, 'store_id' => $user->store_id
            ];
            $this->container->make(ShiftExchangeInterface::class)->created($source);
            $result['info']['number'] = $number;
        } else {
            $result['menu'] = $this->getMenu($user->role_id);
        }
        $result['token'] = $token;

        return $result;
    }

    public function check($uid, $password)
    {
        $user = $this->findBy('uid', $uid);
        if (!$user) {
            throw new ValidateException('用户不存在！');
        }
        if (CommonHelper::hashPassword($user->salt, $password) !== $user->password) {
            throw new ValidateException('验证失败');
        }

        return true;
    }

    public function logout($uid)
    {
        return $this->update(['token' => ''], $uid, 'uid');
    }

    public function getMenu($roleId)
    {
        $roleMenu = $this->container->make(RoleMenuInterface::class)->lists($roleId);
        $menuIds = array_column($roleMenu, 'menu_id');

        return $this->container->make(MenuInterface::class)->lists($menuIds);
    }

    public function OperationList($limit, $page, $uid = 0)
    {
        return $this->container->make(OperationInterface::class)->lists($limit, $page, $uid);
    }
}